package models

import (
	"flag"
	"fmt"
	"os"
	"strings"
	"sync"
	"testing"

	"gitee.com/fengpiaoyao/gologger"
	"gopkg.in/ini.v1"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

//连接初始化
var DBConn *gorm.DB

//初始化等待
var Wait sync.WaitGroup

//日志模版初始化
var Log gologger.LogOutPut

var DicomFileCount int64   //预读dicom文件个数
var ListDicomFile []string //获取文件列表
var Config *Conf           //全局配置文件

//配置文件映射结构体
type Conf struct {
	logLv           string
	outPutType      string
	logpath         string
	dbname          string
	ClearDB         string
	DicomFilePath   string
	ReadDicomEnable bool
	WorkerThread    uint
}

//配置文件初始化
func initConf(path string) *Conf {
	// confpath := flag.String("c", "config.ini", "system config from *.ini")
	confpath := flag.String("c", path, "system config from *.ini")
	testing.Init()
	flag.Parse()
	cfg, err := ini.Load(*confpath)
	if err != nil {
		fmt.Printf("Fail to read file: %v", err)
		os.Exit(1)
	}

	logLv := cfg.Section("LOG").Key("LOG_LEVEL").MustString("UNKNOWN")
	outPutType := cfg.Section("LOG").Key("LOG_OUTTYPE").MustString("console")
	logpath := cfg.Section("LOG").Key("LOG_PATH").MustString("./")
	dbname := cfg.Section("DB").Key("DB_NAME").Validate(func(in string) string {
		if len(in) == 0 {
			defaultDB := "./dicom.db"
			fmt.Printf("[WARNING] DB file config is not set,default set DB= %v\n", defaultDB)
			return defaultDB
		}
		return in
	})
	ClearDB := strings.ToUpper(cfg.Section("DB").Key("DB_CLEAR").MustString("NO"))
	ReadDicomEnable := cfg.Section("DICOM").Key("DICOM_READ").MustBool(false)
	DicomFilePath := cfg.Section("DICOM").Key("DICOM_PATH").Validate(func(in string) string {
		if len(in) == 0 {
			defaultDicomPath := "./data"
			fmt.Printf("[WARNING] Dicomfile path config is not set,default set dicomfilepath= %v\n", defaultDicomPath)
			return defaultDicomPath
		}
		return in
	})
	WorkerThread := cfg.Section("THREAD").Key("WORKER").MustUint(1)
	return &Conf{
		logLv:           logLv,
		outPutType:      outPutType,
		logpath:         logpath,
		dbname:          dbname,
		ClearDB:         ClearDB,
		DicomFilePath:   DicomFilePath,
		ReadDicomEnable: ReadDicomEnable,
		WorkerThread:    WorkerThread,
	}

}

//日志初始化
func initLog(logLv, outPutType, logpath string) {
	Log = gologger.FotmatLog(logLv, outPutType, logpath)
	if logLv == "UNKNOWN" {
		Log.WARNING("log config is not use set,default set logleve =%v", logLv)
	}
	Log.DEBUG("loglevel=%v,logfilepath=%v", logLv, logpath)
	Log.INFO("初始化日志模块完成!!!!")
}

//数据库初始化
func initDB(dbname string) {

	var err error
	DBConn, err = gorm.Open(sqlite.Open(dbname), &gorm.Config{})
	if err != nil {
		Log.FATAL("%w", err)
		panic(err)
	}
	//表注册
	err = DBConn.AutoMigrate(&FileInfo{}, &DicomInfo{})
	if err != nil {
		Log.ERROR("%w", err)
		return
	}
	Log.INFO("初始化数据库完成......")

}

func init() {
	//1读取配置文件
	Config = initConf("./config.ini")
	//2初始化日志模块
	initLog(Config.logLv, Config.outPutType, Config.logpath)
	Log.DEBUG("配置文件读取完成: %+v", Config)
	Log.DEBUG("日志模块初始化完成～！！")

	//3初始化数据库
	initDB(Config.dbname)
	if Config.ClearDB != "NO" {
		var f FileInfo
		var d DicomInfo
		switch Config.ClearDB {
		case "ALL":
			Log.DEBUG("clear all db data")
			f.clear()
			d.clear()
		case "FILE":
			Log.DEBUG("clear file_infos db data")
			f.clear()
		case "DICOM":
			Log.DEBUG("clear dicom_infos db data")
			d.clear()
		default:
			Log.WARNING("conf配置文件中，数据清理配置项目无法识别，请重新设置～！！")
		}
		Log.INFO("数据库清理完成")
	} else {
		Log.INFO("数据库未开启清理服务")
	}

}
